package lt.mockos.app.client.cpu.hw;

import java.util.LinkedList;

import lt.mockos.app.client.cpu.event.SuperChangeEvent;
import lt.mockos.app.client.cpu.hw.descriptor.Descriptor;
import lt.mockos.app.client.cpu.hw.descriptor.ProcessDescriptor;
import lt.mockos.app.client.cpu.hw.descriptor.ResourceDescriptor;
import lt.mockos.app.client.cpu.hw.descriptor.Descriptor.DescriptorType;

import com.google.gwt.event.shared.EventBus;

public class SuperMemory {

    private LinkedList<Descriptor> memory = new LinkedList<Descriptor>();

    private static int count = 0;

    private EventBus eventBus;

    public SuperMemory(EventBus eventBus) {
        this.eventBus = eventBus;
    }

    public Descriptor getDescriptorByTitle(String title) {
        for (Descriptor d : memory)
            if (d.getTitle().contentEquals(title))
                return d;

        return null;
    }

    public LinkedList<ProcessDescriptor> getProcessDescriptors() {
        LinkedList<ProcessDescriptor> descriptors = new LinkedList<ProcessDescriptor>();
        for (Descriptor d : memory) {
            if (d.getDescriptorType() == DescriptorType.PROCESS)
                descriptors.add((ProcessDescriptor) d);
        }
        return descriptors;
    }

    public LinkedList<ResourceDescriptor> getResourceDescriptors() {
        LinkedList<ResourceDescriptor> descriptors = new LinkedList<ResourceDescriptor>();
        for (Descriptor d : memory) {
            if (d.getDescriptorType() == DescriptorType.RESOURCE)
                descriptors.add((ResourceDescriptor) d);
        }
        return descriptors;
    }

    public void add(Descriptor descriptor) {
        descriptor.setID(count++);
        memory.add(descriptor);
        updateView();
    }

    public void remove(Descriptor descriptor) {
        memory.remove(descriptor);
        updateView();
    }

    public void destroyProcess(ProcessDescriptor pd) {
        for (Descriptor d : memory) {
            if (d.getParent().getID() == pd.getID()) {
                if (d.getDescriptorType() == DescriptorType.PROCESS)
                    destroyProcess((ProcessDescriptor) d);
                memory.remove(d);
            } else if (d.getDescriptorType() == DescriptorType.RESOURCE) {
                ResourceDescriptor rd = (ResourceDescriptor) d;
                if (rd.getUsingProcess() != null && rd.getUsingProcess().getID() == pd.getID()) {
                    rd.setUsingProcess(null);
                }

            }
        }
        updateView();
    }

    public void destroyResource(ProcessDescriptor pd) {
        for (Descriptor d : memory) {
            if (d.getDescriptorType() == DescriptorType.RESOURCE) {
                ResourceDescriptor rd = (ResourceDescriptor) d;
                if (rd.getUsingProcess() != null && rd.getUsingProcess().getID() == pd.getID()) {
                    rd.setUsingProcess(null);
                } else if (rd.getParent().getID() == pd.getID()) {
                    memory.remove(rd);
                }
            }
        }
        updateView();
    }

    private void updateView() {
        eventBus.fireEvent(new SuperChangeEvent(""));
    }

    public LinkedList<Descriptor> getMemory() {
        return memory;
    }

}
